home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / miwm.zoo / screen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-07  |  8.0 KB  |  501 lines

  1. #include "screen.h"
  2. #define DEBUG(s) static char *___Xyz = s
  3.  
  4. SCREEN *screen[NUMSCREENS], *current;
  5. void paint();
  6.  
  7. /* utility routines -- assume that src and dst are word aligned */
  8.  
  9. void quickzero(dst, nbytes)
  10.     long *dst; long nbytes;
  11. {
  12.     DEBUG("quickzero");
  13.     unsigned leftover;
  14.     char *foo;
  15.  
  16.     leftover = nbytes & 0x0f;
  17.     nbytes = nbytes >> 4;
  18.     while (nbytes-- > 0) {
  19.         *dst++ = 0; *dst++ = 0;
  20.         *dst++ = 0; *dst++ = 0;
  21.     }
  22.     foo = (char *)dst;
  23.     while (leftover-- > 0)
  24.         *foo++ = 0;
  25. }
  26.  
  27. extern void normal_putch(), escy_putch();
  28.  
  29. void
  30. init(v)
  31.     SCREEN *v;
  32. {
  33.     int i, j;
  34.     extern void *malloc();
  35.     char *foo, *data;
  36.     DEBUG("init");
  37.  
  38.     v->maxx = 80;
  39.     v->maxy = 25;
  40.     v->cx = v->cy = 0;
  41.     v->cwidth = 8;        /* always 8 pixels wide */
  42.     v->cheight = 8;
  43.     v->planesiz = 80;
  44.  
  45.     v->linelen = v->planesiz * v->cheight;
  46.     v->state = normal_putch;
  47.     v->flags = FCURS;
  48.     v->lastlineoff = (v->maxy-1) * v->linelen;
  49.     v->lineoff = (long *)malloc(v->maxy * sizeof(long));
  50.     v->lineoff[0] = 0;
  51.     for (i = 1; i < v->maxy; i++) {
  52.         v->lineoff[i] = v->lineoff[i-1] + v->linelen;
  53.     }
  54.  
  55.     quickzero(v->base, (long)v->lastlineoff + v->linelen);
  56. }
  57.  
  58. /*
  59.  * PLACE(v, x, y): the address corresponding to the upper left hand corner of
  60.  * the character at position (x,y) on screen v
  61.  */
  62. static
  63. #ifdef __GNUC__
  64. inline
  65. #endif
  66. char *PLACE(v, x, y)
  67.     SCREEN *v;
  68.     int x, y;
  69. {
  70.     char *place;
  71.  
  72.     place = x + v->base + v->lineoff[y];
  73.  
  74.     return place;
  75. }
  76.  
  77. /*
  78.  * paint(v, c, x, y): put character 'c' at position (x, y) on screen
  79.  * v. It is assumed that x, y are proper coordinates!
  80.  */
  81. extern char *my_font;
  82.  
  83. void
  84. paint(v, c, x, y)
  85.     SCREEN *v;
  86.     int c, x, y;
  87. {
  88.     DEBUG("paint");
  89.     char *data, *place, d, doinverse;
  90.     int i, j;
  91.     short vplanesiz;
  92.  
  93.     data = (char *)(&my_font+2*(c&0x007f));
  94.     place = PLACE(v, x, y);
  95.     doinverse = (v->flags & FINVERSE) ? 0xff : 0;
  96.  
  97.     vplanesiz = v->planesiz;
  98.  
  99.     for (j = 8; j > 0; --j) {
  100.         place[0] = *data++ ^ doinverse;
  101.         place += vplanesiz;
  102.     }
  103.  
  104. }
  105.  
  106. /*
  107.  * gotoxy (v, x, y): move current cursor address of screen v to (x, y)
  108.  * does nothing if (x,y) is illegal
  109.  */
  110.  
  111. void
  112. gotoxy(v, x, y)
  113.     SCREEN *v;
  114.     int x, y;
  115. {
  116.     DEBUG("gotoxy");
  117.     if (x >= v->maxx || y >= v->maxy || x < 0 || y < 0)
  118.         return;
  119.     v->cx = x;
  120.     v->cy = y;
  121. }
  122.  
  123. /*
  124.  * clrline(v, r): clear line r of screen v
  125.  */
  126.  
  127. void
  128. clrline(v, r)
  129.     SCREEN *v;
  130.     int r;
  131. {
  132.     DEBUG("clrline");
  133.     long *dst;
  134.     long nbytes;
  135.  
  136.     nbytes = v->linelen;
  137.     dst = (long *)(v->base + (r * v->linelen));
  138.  
  139.     quickzero(dst, nbytes);
  140. }
  141.     
  142. /*
  143.  * clear(v): clear the whole screen v
  144.  */
  145.  
  146. void
  147. clear(v)
  148.     SCREEN *v;
  149. {
  150.     DEBUG("clear");
  151.     long *dst;
  152.     long nbytes;
  153.  
  154.     nbytes = v->lastlineoff + v->linelen;
  155.     dst = (long *)v->base;
  156.  
  157.     quickzero(dst, nbytes);
  158. }
  159.  
  160. /*
  161.  * clrchar(v, x, y): clear the (x,y) position on screen v
  162.  */
  163.  
  164. void
  165. clrchar(v, x, y)
  166.     SCREEN *v;
  167.     int x, y;
  168. {
  169.     DEBUG("clrchar");
  170.     int i, j, planesiz;
  171.     char *place;
  172.  
  173.     planesiz = v->planesiz;
  174.  
  175.     place = PLACE(v, x, y);
  176.  
  177.     for (j = 8; j > 0; --j) {
  178.         *place = 0;
  179.         place += planesiz;
  180.     }
  181. }
  182.  
  183. /*
  184.  * clrfrom(v, x1, y1, x2, y2): clear screen v from position (x1,y1) to
  185.  * position (x2, y2) inclusive. It is assumed that y2 >= y1.
  186.  */
  187.  
  188. void
  189. clrfrom(v, x1, y1, x2, y2)
  190.     SCREEN *v;
  191.     int x1,y1,x2,y2;
  192. {
  193.     int i;
  194.  
  195.     DEBUG("clrfrom");
  196.     for (i = x1; i < v->maxx; i++)
  197.         clrchar(v, i, y1);
  198.     if (y2 > y1) {
  199.         for (i = 0; i <= x2; i++)
  200.             clrchar(v, i, y2);
  201.         for (i = y1+1; i < y2; i++)
  202.             clrline(v, i);
  203.     }
  204. }
  205.  
  206. /*
  207.  * delete_line(v, r): delete line r of screen v. The screen below this
  208.  * line is scrolled up, and the bottom line is cleared.
  209.  */
  210.  
  211. #define scroll(v) delete_line(v, 0)
  212.  
  213. void
  214. delete_line(v, r)
  215.     SCREEN *v;
  216.     int r;
  217. {
  218.     DEBUG("delete_line");
  219.     long *src, *dst, nbytes;
  220.  
  221.     if (r == 0)
  222.         nbytes = v->lastlineoff;
  223.     else
  224.         nbytes = v->linelen * (v->maxy - (r+1));
  225.  
  226.     dst = (long *)(v->base + v->lineoff[r]);
  227.     src = (long *)( ((long)dst) + v->linelen);
  228.  
  229.     quickmove(dst, src, nbytes);
  230.  
  231. /* clear the last line */
  232.  
  233.     clrline(v, v->maxy - 1);
  234. }
  235.  
  236. /*
  237.  * insert_line(v, r): scroll all of the screen starting at line r down,
  238.  * and then clear line r.
  239.  */
  240.  
  241. void
  242. insert_line(v, r)
  243.     SCREEN *v;
  244.     int r;
  245. {
  246.     DEBUG("insert_line");
  247.     long *src, *dst;
  248.     int i, limit;
  249.  
  250.     limit = v->maxy - 1;
  251.     for (i = limit-1; i >= r ; --i) {
  252.     /* move line i to line i+1 */
  253.         src = (long *)(v->base + v->lineoff[i]);
  254.         dst = (long *)(v->base + v->lineoff[i+1]);
  255.  
  256.         quickmove(dst, src, (long)v->linelen);
  257.     }
  258.  
  259. /* clear line r */
  260.     clrline(v, r);
  261. }
  262.  
  263. /*
  264.  * putesc(v, c): handle the control sequence ESC c
  265.  */
  266.  
  267. void
  268. putesc(v, c)
  269.     SCREEN *v;
  270.     int c;
  271. {
  272.     DEBUG("putesc");
  273.     int cx, cy;
  274.  
  275.     cx = v->cx; cy = v->cy;
  276.  
  277.     switch (c) {
  278.     case 'A':        /* cursor up */
  279.         gotoxy(v, cx, cy-1);
  280.         break;
  281.     case 'B':        /* cursor down */
  282.         gotoxy(v, cx, cy+1);
  283.         break;
  284.     case 'C':        /* cursor right */
  285.         gotoxy(v, cx+1, cy);
  286.         break;
  287.     case 'D':        /* cursor left */
  288.         gotoxy(v, cx-1, cy);
  289.         break;
  290.     case 'E':        /* clear home */
  291.         clear(v);
  292.         /* fall through... */
  293.     case 'H':        /* cursor home */
  294.         gotoxy(v, 0, 0);
  295.         break;
  296.     case 'I':        /* cursor up, insert line */
  297.         if (cy == 0)
  298.             insert_line(v, 0);
  299.         else
  300.             gotoxy(v, cx, cy-1);
  301.         break;
  302.     case 'J':        /* clear below cursor */
  303.         clrfrom(v, cx, cy, v->maxx-1, v->maxy-1);
  304.         break;
  305.     case 'K':        /* clear remainder of line */
  306.         clrfrom(v, cx, cy, v->maxx-1, cy);
  307.         break;
  308.     case 'L':        /* insert a line */
  309.         insert_line(v, cy);
  310.         gotoxy(v, 0, cy);
  311.         break;
  312.     case 'M':        /* delete line */
  313.         delete_line(v, cy);
  314.         gotoxy(v, 0, cy);
  315.         break;
  316.     case 'Y':
  317.         v->state = escy_putch;
  318.         return;        /* YES, this should be 'return' */
  319.  
  320.     case 'd':        /* clear to cursor position */
  321.         clrfrom(v, 0, 0, cx, cy);
  322.         break;
  323.     case 'e':        /* enable cursor */
  324.         v->flags |= FCURS;
  325.         flash_on(v);
  326.         break;
  327.     case 'f':        /* cursor off */
  328.         flash_off(v);
  329.         v->flags &= ~FCURS;
  330.         break;
  331.     case 'j':        /* save cursor position */
  332.         v->savex = v->cx;
  333.         v->savey = v->cy;
  334.         break;
  335.     case 'k':        /* restore saved position */
  336.         gotoxy(v, v->savex, v->savey);
  337.         break;
  338.     case 'l':        /* clear line */
  339.         clrline(v, cy);
  340.         gotoxy(v, 0, cy);
  341.         break;
  342.     case 'o':        /* clear from start of line to cursor */
  343.         clrfrom(v, 0, cy, cx, cy);
  344.         break;
  345.     case 'p':        /* reverse video on */
  346.         v->flags |= FINVERSE;
  347.         break;
  348.     case 'q':        /* reverse video off */
  349.         v->flags &= ~FINVERSE;
  350.         break;
  351.     case 'v':        /* wrap on */
  352.         v->flags |= FWRAP;
  353.         break;
  354.     case 'w':
  355.         v->flags &= ~FWRAP;
  356.         break;
  357.     }
  358.     v->state = normal_putch;
  359. }
  360.  
  361. /*
  362.  * escy1_putch(v, c): for when an ESC Y + char has been seen
  363.  */
  364. void
  365. escy1_putch(v, c)
  366.     SCREEN *v;
  367.     int c;
  368. {
  369.     gotoxy(v, c - ' ', v->escy1 - ' ');
  370.     v->state = normal_putch;
  371. }
  372.  
  373. /*
  374.  * escy_putch(v, c): for when an ESC Y has been seen
  375.  */
  376. void
  377. escy_putch(v, c)
  378.     SCREEN *v;
  379.     int c;
  380. {
  381.     v->escy1 = c;
  382.     v->state = escy1_putch;
  383. }
  384.  
  385. /*
  386.  * normal_putch(v, c): put character 'c' on screen 'v'. This is the default
  387.  * for when no escape, etc. is active
  388.  */
  389.  
  390. void
  391. normal_putch(v, c)
  392.     SCREEN *v;
  393.     int c;
  394. {
  395.     DEBUG("normal_putch");
  396.     int cx, cy;
  397.     int state;
  398.  
  399.     cx = v->cx; cy = v->cy;
  400.  
  401. /* control characters */
  402.     if (c < ' ') {
  403.         switch (c) {
  404.         case '\r':
  405.             gotoxy(v, 0, cy);
  406.             return;
  407.         case '\n':
  408.             if (cy == v->maxy - 1)
  409.                 scroll(v);
  410.             else
  411.                 gotoxy(v, cx, cy+1);
  412.             return;
  413.         case '\b':
  414.             gotoxy(v, cx-1, cy);
  415.             return;
  416.         case '\007':        /* BELL */
  417.             Bconout(2, 7);
  418.             return;
  419.         case '\033':        /* ESC */
  420.             v->state = putesc;
  421.             return;
  422.         case '\t':
  423.             state = 8 - ((v->cx & 7));
  424.             while(state > 0) {
  425.                 normal_putch(v, ' ');
  426.                 state--;
  427.             }
  428.             return;
  429.         default:
  430.             return;
  431.         }
  432.     }
  433.  
  434.     paint(v, c, cx, cy);
  435.     v->cx++;
  436.     if (v->cx == v->maxx) {
  437.         if (v->flags & FWRAP) {
  438.             v->cx = 0;
  439.             normal_putch(v, '\n');
  440.         }
  441.         else 
  442.             v->cx--;
  443.     }
  444. }
  445.  
  446. void
  447. put_ch(v, c)
  448.     SCREEN *v;
  449.     int c;
  450. {
  451.     (*(v->state))(v, c & 0x00ff);
  452. }
  453.  
  454. /* routines for flashing the cursor for screen v */
  455.  
  456. static void
  457. flash(v)
  458.     SCREEN *v;
  459. {
  460.     char *place;
  461.     int i, j;
  462.     short vplanesiz;
  463.     int x, y;
  464.  
  465.     vplanesiz = v->planesiz;
  466.     x = v->cx; y = v->cy;
  467.  
  468.     place = PLACE(v, x, y);
  469.  
  470.     for (j = 8; j > 0; --j) {
  471.       (*place)^= 0xff;
  472.       place += vplanesiz;
  473.     }
  474. }
  475.  
  476. /* make sure the cursor is off */
  477.  
  478. void
  479. flash_off(v)
  480.     SCREEN *v;
  481. {
  482.     if (v->flags & FFLASH) {
  483.         v->flags ^= FFLASH;
  484.         flash(v);
  485.     }
  486. }
  487.  
  488. /* make sure the cursor is on (if it's enabled, of course!) */
  489.  
  490. void
  491. flash_on(v)
  492.     SCREEN *v;
  493. {
  494.     if (v->flags & FFLASH)
  495.         return;
  496.     if (v->flags & FCURS) {
  497.         v->flags |= FFLASH;
  498.         flash(v);
  499.     }
  500. }
  501.